home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
vector.lha
/
vector
/
colorvector.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-23
|
2KB
|
122 lines
#include "colorvector.h"
static inline float min(float a, float b) { return (a < b) ? a : b; }
static inline float max(float a, float b) { return (a > b) ? a : b; }
static inline float clamp(float v, float min, float max) {
return (v < min) ? min : (v > max) ? max : v;
}
// Algorithms converted (with minor bug fixes) from Rogers
static void hsv_to_rgb(
float h, float s, float v,
float &r, float &g, float &b) {
h = clamp(h, 0, 360);
s = clamp(s, 0, 1);
v = clamp(v, 0, 1);
if (s == 0.0)
r = g = b = v;
else {
// Chromatic case
if (h < 0) h = 0;
else if (h > 360) h = 360;
if (h == 360)
h = 0;
h /= 60.0;
int i = int(floor(h));
float f = h - i,
m = v * (1 - s),
n = v * (1 - s * f),
k = v * (1 - s * (1 - f));
switch (i) {
case 0:
r = v;
g = k;
b = m;
break;
case 1:
r = n;
g = v;
b = m;
break;
case 2:
r = m;
g = v;
b = k;
break;
case 3:
r = m;
g = n;
b = v;
break;
case 4:
r = k;
g = m;
b = v;
break;
case 5:
r = v;
g = m;
b = n;
break;
}
}
}
static void rgb_to_hsv(
float r, float g, float b,
float &h, float &s, float &v) {
r = clamp(r, 0, 1);
g = clamp(g, 0, 1);
b = clamp(b, 0, 1);
// Value
v = max(r, max(g, b));
// Saturation
float temp = min(r, min(g, b));
if (v == 0.0)
s = 0;
else
s = (v - temp) / v;
// Hue
if (s == 0.0)
h = 0; // Undefined
else {
float Cr = (v - r) / (v - temp),
Cg = (v - g) / (v - temp),
Cb = (v - b) / (v - temp);
if (r == v) // Between yellow & magenta
h = Cb - Cg;
else if (g == v) // Between cyan & yellow
h = 2 + Cr - Cb;
else // if (b == v) // Between magenta & cyan
h = 4 + Cg - Cr;
h *= 60;
if (h < 0)
h += 360;
}
}
RGBcolor &RGBcolor::operator=(HSVcolor &c) {
hsv_to_rgb(c(0), c(1), c(2), (*this)[0], (*this)[1], (*this)[2]);
return *this;
}
HSVcolor &HSVcolor::operator=(RGBcolor &c) {
rgb_to_hsv(c(0), c(1), c(2), (*this)[0], (*this)[1], (*this)[2]);
return *this;
};